#ifndef TEMPLE_UTIL_MACRO_H_
#define TEMPLE_UTIL_MACRO_H_

#define INJECT1(C,M1) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1) {} \
	inline C(C &&r) : M1(std::move(r.M1)) {} \
	inline C &operator=(const C &r) { M1=r.M1; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); return *this; }

#define INJECT2(C,M1,M2) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); return *this; }

#define INJECT3(C,M1,M2,M3) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); return *this; }

#define INJECT4(C,M1,M2,M3,M4) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); return *this; }

#define INJECT5(C,M1,M2,M3,M4,M5) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4), M5(r.M5) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)), M5(std::move(r.M5)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; M5=r.M5; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); M5=std::move(r.M5); return *this; }

#define INJECT6(C,M1,M2,M3,M4,M5,M6) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4), M5(r.M5), M6(r.M6) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)), M5(std::move(r.M5)), M6(std::move(r.M6)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; M5=r.M5; M6=r.M6; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); M5=std::move(r.M5); M6=std::move(r.M6); return *this; }

#define INJECT7(C,M1,M2,M3,M4,M5,M6,M7) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4), M5(r.M5), M6(r.M6), M7(r.M7) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)), M5(std::move(r.M5)), M6(std::move(r.M6)), M7(std::move(r.M7)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; M5=r.M5; M6=r.M6; M7=r.M7; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); M5=std::move(r.M5); M6=std::move(r.M6); M7=std::move(r.M7); return *this; }

#define INJECT8(C,M1,M2,M3,M4,M5,M6,M7,M8) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4), M5(r.M5), M6(r.M6), M7(r.M7), M8(r.M8) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)), M5(std::move(r.M5)), M6(std::move(r.M6)), M7(std::move(r.M7)), M8(std::move(r.M8)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; M5=r.M5; M6=r.M6; M7=r.M7; M8=r.M8; return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); M5=std::move(r.M5); M6=std::move(r.M6); M7=std::move(r.M7); M8=std::move(r.M8); return *this; }

#define INJECT9(C,M1,M2,M3,M4,M5,M6,M7,M8,M9) \
	inline C() {} \
	inline C(const C &r) : M1(r.M1), M2(r.M2), M3(r.M3), M4(r.M4), M5(r.M5), M6(r.M6), M7(r.M7), M8(r.M8), M9(r.M9) {} \
	inline C(C &&r) : M1(std::move(r.M1)), M2(std::move(r.M2)), M3(std::move(r.M3)), M4(std::move(r.M4)), M5(std::move(r.M5)), M6(std::move(r.M6)), M7(std::move(r.M7)), M8(std::move(r.M8)), M9(std::move(r.M9)) {} \
	inline C &operator=(const C &r) { M1=r.M1; M2=r.M2; M3=r.M3; M4=r.M4; M5=r.M5; M6=r.M6; M7=r.M7; M8=r.M8; M9=r.M9;  return *this; } \
	inline C &operator=(C &&r) { M1=std::move(r.M1); M2=std::move(r.M2); M3=std::move(r.M3); M4=std::move(r.M4); M5=std::move(r.M5); M6=std::move(r.M6); M7=std::move(r.M7); M8=std::move(r.M8); M9=std::move(r.M9); return *this; }

#endif //TEMPLE_UTIL_MACRO_H_
